package com.qkun.library.utils;

import android.Manifest;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.provider.Settings;

import androidx.core.content.ContextCompat;

import com.qkun.library.R;
import com.qkun.library.base.BaseActivity;
import com.qkun.library.base.BaseApplication;
import com.qkun.library.widget.BottomDialog;

import java.lang.reflect.InvocationTargetException;

/**
 * @author qinkun
 * @date 5/28 0028 22:13
 * @description
 */
public final class SpecialPermissionProcessor {

    /**
     * TODO: 6/1 0001 待考虑是否需要使用 WeakReference
     *
     * @param ctx
     * @param permissionsCallback
     */
    public static void requestOverlayPermissionShort(final Context ctx, final ResultProcessor.OnPermissionsCallback permissionsCallback) {
        final Context context = Utils.requireNonNull(ctx).getApplicationContext();
        Utils.requireNonNull(permissionsCallback);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.canDrawOverlays(context)) {
                permissionsCallback.onGranted(Manifest.permission.SYSTEM_ALERT_WINDOW);
            } else {
//                baseActivity.getBaseContext();
                final String basePackageName = context.getPackageName();
                int colorPrimaryResId = context.getResources().getIdentifier("colorPrimary", "color", basePackageName);
                int colorPrimary = Utils.getColor(colorPrimaryResId);

                final BottomDialog.OnCancelListener onCancelListener = new BottomDialog.OnCancelListener() {
                    @Override
                    public void onCancel(BottomDialog dialog) {
                        permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
                    }
                };

                BottomDialog.make(ctx)
                        .setMessage(R.string.overlay_permission_hint_short)
                        .setIcon(ContextCompat.getDrawable(context, R.drawable.ic_not_have_permission), colorPrimary)
                        .setCancelListener(onCancelListener)
                        .addButton(R.string.to_grant, colorPrimary, new BottomDialog.OnDialogClickListener() {
                            @Override
                            public void onClick(final BottomDialog dialog, int which) {
                                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
                                intent.setData(Uri.parse("package:" + basePackageName));
                                final BaseActivity baseActivity = dialog.getActivity();
                                if (Utils.nonNull(baseActivity)) {
                                    ResultProcessor.startActivityForResult(baseActivity, intent, new ResultProcessor.OnActivityCallback() {
                                        @Override
                                        public void onActivityResult(int resultCode, Intent data) {
                                            dialog.dismiss();
                                            //魅族6.0以上的跳转会自动退出，所以需要做启动失败处理
                                            if (resultCode == BaseActivity.RESULT_FAIL) {
                                                permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
                                                int colorGray70 = Utils.getColor(R.color.colorGray70);
                                                Drawable failDrawable = DrawableUtils.toTintDrawable(ContextCompat.getDrawable(
                                                        BaseApplication.getAppContext(), R.drawable.ic_fail), colorGray70);

                                                BottomDialog.make(ctx)
                                                        .setMessage(R.string.overlay_permission_grant_error_hint)
                                                        .setIcon(failDrawable)
                                                        .setCancelListener(onCancelListener)
                                                        .addDismissButton(R.string.sure, colorGray70, new BottomDialog.OnDialogClickListener() {
                                                            @Override
                                                            public void onClick(BottomDialog dialog, int which) {
                                                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                                                intent.setData(Uri.parse("package:" + basePackageName));
                                                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                                                ctx.startActivity(intent);
                                                            }
                                                        })
                                                        .show();
                                            } else {
                                                if (Settings.canDrawOverlays(context)) {
                                                    permissionsCallback.onGranted(Manifest.permission.SYSTEM_ALERT_WINDOW);
                                                } else {
                                                    permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
                                                }
                                            }
                                        }
                                    });
                                } else {
                                    MyLog.e("DialogActivity is Null!!!");
                                    permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
                                }
                            }
                        })
                        .show();
            }
        } else if (ctx instanceof BaseActivity) {
            ResultProcessor.requestPermissions((BaseActivity) ctx, new String[]{Manifest.permission.SYSTEM_ALERT_WINDOW}, permissionsCallback);
        } else {
            MyLog.e("Ctx must be BaseActivity!!!");
            permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
        }
    }

    public static void requestOverlayPermission(final Context ctx, final ResultProcessor.OnPermissionsCallback permissionsCallback) {
        final Context context = Utils.requireNonNull(ctx).getApplicationContext();
        Utils.requireNonNull(permissionsCallback);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.canDrawOverlays(context)) {
                permissionsCallback.onGranted(Manifest.permission.SYSTEM_ALERT_WINDOW);
            } else {
                permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
                final String basePackageName = context.getPackageName();
                int colorPrimaryResId = context.getResources().getIdentifier("colorPrimary", "color", basePackageName);
                int colorPrimary = Utils.getColor(colorPrimaryResId);

                BottomDialog.make(ctx)
                        .setMessage(R.string.overlay_permission_hint)
                        .setIcon(ContextCompat.getDrawable(context, R.drawable.ic_not_have_permission), colorPrimary)
                        .canCancel(true)
                        .addDismissButton(R.string.to_grant, colorPrimary, new BottomDialog.OnDialogClickListener() {
                            @Override
                            public void onClick(final BottomDialog dialog, int which) {
                                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                intent.setData(Uri.parse("package:" + basePackageName));
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                ctx.startActivity(intent);
                            }
                        })
                        .show();
            }
        } else if (ctx instanceof BaseActivity) {
            ResultProcessor.requestPermissions((BaseActivity) ctx, new String[]{Manifest.permission.SYSTEM_ALERT_WINDOW}, permissionsCallback);
        } else {
            MyLog.e("Ctx must be BaseActivity!!!");
            permissionsCallback.onDenied(Manifest.permission.SYSTEM_ALERT_WINDOW);
        }
    }

    /**
     * 检查悬浮权限是否授予
     * 19以前通常是可以直接授予了的
     * 在23到19之前，因为无Settings.canDrawOverlays(context)方法，所以需使用appOpsManager的checkOp方法检查
     * 23及其之后需使用Settings.canDrawOverlays(context)方法检查
     *
     * @return
     */
    public static boolean canDrawOverlays() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return Settings.canDrawOverlays(BaseApplication.getAppContext());
        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Object appOpsManager = BaseApplication.getAppContext().getSystemService(Context.APP_OPS_SERVICE);
            if (Utils.nonNull(appOpsManager)) {
                try {
                    // 该24是指AppOpsManager.OP_SYSTEM_ALERT_WINDOW
                    Object mode = appOpsManager.getClass()
                            .getMethod("checkOp", Integer.TYPE, Integer.TYPE, String.class)
                            .invoke(appOpsManager,
                                    24,
                                    Binder.getCallingUid(),
                                    BaseApplication.getAppContext().getPackageName());
                    if (Utils.nonNull(mode) && (mode instanceof Integer)) {
                        // 4.4至6.0之间的非国产手机，例如samsung，sony一般都可以直接添加悬浮窗，
                        // 这时候它的值一般是MODE_IGNORED，所以需要判断是否是国产等等之类的
                        return ((Integer) mode == AppOpsManager.MODE_ALLOWED) || !CheckRomUtils.isFromChina();
                    }
                } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
                    MyLog.e(e);
                }
            }
            return false;
        }
        return true;
    }

}
